var bind = {};

/**
 * 事件队列
 */
bind.eventQueue={
    queue: {}, /*存储[事件处理函数]: Memory(内存中获取)*/
    record: {}, /*存储[事件处理函数名]: String*/
    source: {}, /*存储[绑定的事件的源代码(toString()的结果):String]*/
    elemObj: {}, /*存储[DOM节点和其被注册的事件集合({dom:xxx,store: [...]})],Object*/
    add:function(type,func,obj) {
        if(typeof(type)!='string'||type.length<1) {
            console.error('parameter "type" should be a string with length geater than 0');
            return;
        }
        if(typeof(func)!='function') {
            console.error('parameter "func" should a function');
            return;
        }
        var _ret=undefined;
        var _value=this.queue[type];
        var _source=this.source[type];
        if(JS.type(_value)==='Undefined'||_value===null) {
            this.queue[type]={};
            this.source[type]={};
            _ret=type+'_0_0';
            this.record[type]=[_ret];
            var objItem={dom: obj,store: [type+'_0']};
            this.elemObj[type]=[objItem];
            _value=this.queue[type];
            _source=this.source[type];
        }
        else {
            var i=0,j=0;
            var isExist=false;
            var _tmpElem=undefined;
            for(var _elem in this.elemObj[type]) {
                _tmpElem=this.elemObj[type][_elem];
                if(JS.type(_tmpElem)!=='Undefined'&&_tmpElem!==null) {
                    if(_tmpElem.dom==obj) {
                        j=_tmpElem.store.length;
                        _tmpElem.store.push(type+'_'+j);
                        isExist=true;
                        break;
                    }
                }
            }
            if(!isExist) {
                var objItem={dom: obj,store: [type+'_0']};
                if(!this.elemObj[type]) {
                    this.elemObj[type] = [];
                }
                this.elemObj[type].push(objItem);
                j=0;
            }
            i=this.elemObj[type].length;
            i=i>1?(i-1):0;
            _ret=[type,'_',i,'_',j].join('');
            if(!this.record[type]) {
                this.record[type] = [];
            }
            this.record[type].push(_ret);
        }
        if(!this._events) {
            this._events = {};
        }
        this._events[_ret] = function(eve) {
            return func(eve);
        };
        _value[_ret]=this._events[_ret];
        _source[_ret]=func.toString();
        return _ret;
    },
    remove: function(type,func,obj) {
        if(typeof(type)!='string'||type.length<1) {
            console.error('parameter "type" should be a string with length geater than 0');
            return;
        }
        var _value=this.queue[type];
        var _source=this.source[type];
        var _rec=this.record[type];
        var elem=this.elemObj[type];
        if(_value==undefined||_value==null) {
            return;
        }
        var _tmpElem=undefined;
        var i=0;
        for(var _elem in this.elemObj[type]) {
            _tmpElem=this.elemObj[type][_elem];
            i++;
            if(_tmpElem!=undefined&&_tmpElem!=null) {
                if(_tmpElem.dom==obj) {
                    break;
                }
            }
        }
        var _func=undefined;
        if(typeof(func)!='function') { /*如果未指定具体的事件代码，则清除所有type类型的事件*/
            for(var _i in _tmpElem.store) {
                var _tmpArr=_tmpElem.store[_i].split('_');
                var _tmp=[_tmpArr[0],'_',i,'_',_tmpArr[1]].join('');
                if(array.has(_rec,_tmp)) {
                    array.remove(_rec,_rec[_i]);
                }
            }
            array.clear(_tmpElem.store);
        }
        else {
            _func=func.toString();
        }
        for(var _index in _value) {
            if(_func==undefined) {
                delete _value[_index];
                delete _source[_index];
            }
            else {
                if(_value[_index]!=undefined&&_value[_index]!=null&&_source[_index]==_func) {
                    array.remove(_rec,_index);
                    array.remove(_tmpElem.store,_index);
                    delete _value[_index];
                    delete _source[_index];
                    break;
                }
            }
        }
    },
    getKey:function(type,func,obj) {
        if(typeof(type)!='string'||type.length<1) {
            console.error('parameter "type" should be a string with length geater than 0');
            return;
        }
        var _value=this.queue[type];
        var _source=this.source[type];
        var _rec=this.record[type];
        var _elemObj=this.elemObj[type];
        if(JS.type(_value)=='Undefined'||_value===null) {
            return undefined;
        }
        var _tmpElem=undefined;
        for(var _elem in _elemObj) {
            _tmpElem=_elemObj[_elem];
            if(JS.type(_tmpElem)!=='Undefined'&&_tmpElem!==null) {
                if(_tmpElem.dom===obj) {
                    break;
                }
            }
        }
        if(JS.type(_tmpElem)==='Undefined'||_tmpElem===null) {
            return undefined;
        }
        var _i=array.indexOf(_elemObj,_tmpElem);
        var _func=undefined;
        if(typeof(func)=='function') {
            _func=func.toString();
        }
        var _ret=undefined;
        var isOut=false;
        if(_func!=undefined) {
            for(var _index in _value) {
                if(JS.type(_value[_index])!=='Undefined'&&_value[_index]!==null&&_source[_index]==_func) {
                    _ret=_index;
                    for(var _name in _tmpElem.store) {
                        var _tmpArr=_tmpElem.store[_name].split('_');
                        var _tmp=[_tmpArr[0],'_',_i,'_',_tmpArr[1]].join('');
                        if(array.has(_rec,_tmp)&&_ret==_tmp) {
                            isOut=true;
                            break;
                        }
                    }
                }
                if(isOut) {
                    break;
                }
            }
        }
        return _ret;
    },
    allKey:function(type,obj) {
        if(typeof(type)!='string'||type.length<1) {
            console.error('parameter "type" should be a string with length geater than 0');
            return;
        }
        var _value=this.queue[type];
        var _source=this.source[type];
        var _elemObj=this.elemObj[type];
        if(_value==undefined||_value==null) {
            return undefined;
        }
        var _tmpElem=undefined;
        for(var _elem in _elemObj) {
            _tmpElem=_elemObj[_elem];
            if(JS.type(_tmpElem)!=='Undefined'&&_tmpElem!==null) {
                if(_tmpElem.dom===obj) {
                    break;
                }
            }
        }
        if(JS.type(_tmpElem)=='Undefined'||_tmpElem===null) {
            return undefined;
        }
        var _i=array.indexOf(_elemObj,_tmpElem);
        var _ret=[];
        for(var _index in _tmpElem.store) {
            var _item=_tmpElem.store[_index];
            var _tmpArr=_item.split('_');
            var _tmp=[_tmpArr[0],'_',_i,'_',_tmpArr[1]].join('');
            if(typeof _tmp=='string') {
                _ret.push(_tmp);
            }
        }
        return _ret;
    }
};
/**
 * 功能: 添加事件绑定
 * 参数: eventName: 事件名,listener: 事件,obj: 要添加的事件绑定的对象(可选，未设置时为window或document)
 */
bind.addEvent=function(eventName,listener,obj,eve) {
    if(obj==undefined) {
        var _event=window['on'+eventName];
        if(JS.type(_event)!=='Undefined') {
            obj=window;
        }
        else {
            obj=document;
        }
    }
    if(typeof(listener)!='function') {
        console.error('parameter "listener" should a function');
        return undefined;
    }
    if(typeof(obj)=='string') {
        obj=query.all(obj);
        if(obj.length==1) {
            obj=obj[0];
        }
    }
    if(obj instanceof NodeList) {
        var rets=[];
        for (var i = 0; i < obj.length; i++) {
            rets.push(bind._addEvent(eventName,listener,obj[i]));
        }
        return rets;
    }
    else {
        return bind._addEvent(eventName,listener,obj);
    }
};
/**
 * 功能: 事件注册(仅供内部使用,未验证参数合法性)
 */
bind._addEvent=function(eventName,listener,obj) {
    var _handler=bind.eventQueue.add(eventName,listener,obj); /*得到时间处理函数名,String*/
    var _listener=bind.eventQueue.queue[eventName][_handler]; /*得到事件处理函数:Memory*/
    if(document.addEventListener) {
        obj.addEventListener(eventName,_listener,false);
    } else {
        obj.attachEvent("on"+eventName,_listener);
    }
    return listener;
};
/**
 * 功能: 移除事件绑定
 * 参数: eventName: 事件名,listener: 事件,obj: 要添加的事件绑定的对象(可选，未设置时为window或document)
 */
bind.removeEvent=function(eventName,listener,obj) {
    if(obj==undefined) {
        var _event=window['on'+eventName];
        if(JS.type(_event)!=='Undefined') {
            obj=window;
        }
        else {
            obj=document;
        }
    }
    if(obj instanceof NodeList) {
        for (var i = 0; i < obj.length; i++) {
            bind._removeEvent(eventName,listener,obj[i]);
        }
    }
    else {
        bind._removeEvent(eventName,listener,obj);
    }
};
/**
 * 功能: 事件移除(仅供内部使用,未验证参数合法性)
 */
bind._removeEvent=function(eventName,listener,obj) {
    if(eventName=='mouseEnter') {
        eventName=JS.type(obj.onmouseenter)!=='Undefined'?'mouseenter':'mouseover';
    }
    else if(eventName=='mouseLeave') {
        eventName=JS.type(obj.onmouseleave)!=='Undefined'?'mouseleave':'mouseout';
    }
    var _handler=undefined;
    if(typeof(listener)!='function') {
        _handler=bind.eventQueue.allKey(eventName,obj);
    }
    else {
        _handler=new Array();
        var _tmp=bind.eventQueue.getKey(eventName,listener,obj);
        if(_tmp!=undefined&&((typeof _tmp)=='string')) {
            _handler.push(_tmp);
        }
    }
    for(var _i=0;_i<_handler.length;_i++) {
        if((typeof _handler[_i])!='string') {
            continue;
        }
        var _listener=bind.eventQueue.queue[eventName][_handler[_i]];
        if(document.removeEventListener) {
            obj.removeEventListener(eventName,_listener,false);
        } else {
            obj.detachEvent("on"+eventName,_listener);
        }
    }
    bind.eventQueue.remove(eventName,listener,obj);
};

/**
 * 为元素添加mouseLeave事件(本质为mouseover加区域判断)
 */
query.mouseLeave=function(elem,callBack) {
    if(query.isNode(elem)&&JS.type(elem.onmouseleave)!=='Undefined') {
        return query.addEvent('mouseleave',callBack,elem);
    }
    else {
        return query.addEvent('mouseout',function(eve) {
            eve=eve||window.event;
            var x=eve.clientX; 
            var y=eve.clientY; 
            var _px1 = elem.offsetLeft; 
            var _py1 = elem.offsetTop; 
            var _px2 = elem.offsetLeft + elem.offsetWidth; 
            var _py2 = elem.offsetTop + elem.offsetHeight;
            if(x<_px1||x>_px2||y<_py1||y>_py2){ 
                callBack(eve); 
            }
        },elem);
    }
};
/**
 * 为元素添加mouseEnter事件(本质为mouseover加区域判断)
 */
query.mouseEnter=function(elem,callBack) {
    if(query.isNode(elem)&&JS.type(elem.onmouseenter)!=='Undefined') {
        return query.addEvent('mouseenter',callBack,elem);
    }
    else {
        return query.addEvent('mouseover',function(eve) {
            eve=eve||window.event;
            var x=eve.clientX; 
            var y=eve.clientY; 
            var _px1 = elem.offsetLeft; 
            var _py1 = elem.offsetTop; 
            var _px2 = elem.offsetLeft + elem.offsetWidth; 
            var _py2 = elem.offsetTop + elem.offsetHeight;
            if(x>=_px1&&x<=_px2&&y>=_py1&&y<=_py2){ 
                callBack(eve); 
            }
        },elem);
    }
};

/**
 * DOM加载完成
 */
bind.ready=function(callBack) {
    if(document.readyState=="complete") {
        callBack();
    }
    else {
        var brow=query.browser();
        if(brow.name=='IE'&&brow.version<9) {
            var waitExec=function() {
                arguments.callee(callBack);
            };
            bind.addEvent('readystatechange',waitExec,document);
        }
        else {
            bind.addEvent('DOMContentLoaded',callBack,document);
        }
    }
};